asyncapi: '3.0.0'
info:
  title: Teams Messages
  version: '1'
  description: |
    AsyncAPI definition for team-related operations in the banking system.
    This API enables the creation and management of organisation teams, team invitations,
    team membership and member roles.

    :::warning
        Please note that all the *Commands* and *Events* are wrapped into *Envelope* before being dispatched via Channels.
    :::

    Specific properties that are present in the metadata section of the envelope varied per message.
    The list of required metadata properties is provided in the header's documentation of the corresponding message.

    See this <Link href="/docs/index.html">page</Link> for the more details on the *Envelope* structure and other cross-cutting concerns.

operations:
  # commands
  CreateTeam:
    action: receive
    channel:
      $ref: '#/channels/teams.command.create-team'
    messages:
      - $ref: '#/channels/teams.command.create-team/messages/CreateTeamCommand'

  AddTeamMember:
    action: receive
    channel:
      $ref: '#/channels/teams.command.add-team-member'
    messages:
      - $ref: '#/channels/teams.command.add-team-member/messages/AddTeamMemberCommand'

  AcceptInvitation:
    action: receive
    channel:
      $ref: '#/channels/teams.command.accept-team-invitation'
    messages:
      - $ref: '#/channels/teams.command.accept-team-invitation/messages/AcceptInvitationCommand'

  # events
  TeamCreated:
    action: send
    channel:
      $ref: '#/channels/teams.event.team-created'
    messages:
      - $ref: '#/channels/teams.event.team-created/messages/TeamCreatedEvent'

  MemberRoleUpdated:
    action: send
    channel:
      $ref: '#/channels/teams.event.team-member-role-updated'
    messages:
      - $ref: '#/channels/teams.event.team-member-role-updated/messages/MemberRoleUpdatedEvent'

  MemberSuspended:
    action: send
    channel:
      $ref: '#/channels/teams.event.team-member-suspended'
    messages:
      - $ref: '#/channels/teams.event.team-member-suspended/messages/MemberSuspendedEvent'

  MemberUnsuspended:
    action: send
    channel:
      $ref: '#/channels/teams.event.team-member-unsuspended'
    messages:
      - $ref: '#/channels/teams.event.team-member-unsuspended/messages/MemberUnsuspendedEvent'

  AcceptInvitationFailed:
    action: send
    channel:
      $ref: '#/channels/teams.event.accept-invitation-failed'
    messages:
      - $ref: '#/channels/teams.event.accept-invitation-failed/messages/AcceptInvitationFailedEvent'

  InvitationInitiated:
    action: send
    channel:
      $ref: '#/channels/teams.event.team-invitation-initiated'
    messages:
      - $ref: '#/channels/teams.event.team-invitation-initiated/messages/InvitationInitiatedEvent'

  MemberAddedToTeam:
    action: send
    channel:
      $ref: '#/channels/teams.event.member-added-to-team'
    messages:
      - $ref: '#/channels/teams.event.member-added-to-team/messages/MemberAddedToTeamEvent'

  LinkUserToOrganisationFailed:
    action: send
    channel:
      $ref: '#/channels/teams.event.link-user-to-organisation-failed'
    messages:
      - $ref: '#/channels/teams.event.link-user-to-organisation-failed/messages/LinkUserToOrganisationFailedEvent'

  UserAddedToAccount:
    action: send
    channel:
      $ref: '#/channels/teams.event.user-added-to-account'
    messages:
      - $ref: '#/channels/teams.event.user-added-to-account/messages/UserAddedToAccountEvent'

  UserRemovedFromAccount:
    action: send
    channel:
      $ref: '#/channels/teams.event.user-removed-from-account'
    messages:
      - $ref: '#/channels/teams.event.user-removed-from-account/messages/UserRemovedFromAccountEvent'

  UserPersonalDetailsUpdated:
    action: receive
    channel:
      $ref: '#/channels/authentication.event.user-personal-details-updated'
    messages:
      - $ref: '#/channels/authentication.event.user-personal-details-updated/messages/UserPersonalDetailsUpdatedEvent'

channels:
  teams.command.create-team:
    address: teams.command.create-team
    x-eventcatalog-role: provider
    messages:
      CreateTeamCommand:
        $ref: '#/components/messages/CreateTeamCommand'

  teams.command.add-team-member:
    address: teams.command.add-team-member
    x-eventcatalog-role: provider
    messages:
      AddTeamMemberCommand:
        $ref: '#/components/messages/AddTeamMemberCommand'

  teams.command.accept-team-invitation:
    address: teams.command.accept-team-invitation
    x-eventcatalog-role: provider
    messages:
      AcceptInvitationCommand:
        $ref: '#/components/messages/AcceptInvitationCommand'

  teams.event.team-created:
    address: teams.event.team-created
    x-eventcatalog-role: provider
    messages:
      TeamCreatedEvent:
        $ref: '#/components/messages/TeamCreatedEvent'

  teams.event.team-member-role-updated:
    address: teams.event.team-member-role-updated
    x-eventcatalog-role: provider
    messages:
      MemberRoleUpdatedEvent:
        $ref: '#/components/messages/MemberRoleUpdatedEvent'

  teams.event.team-member-suspended:
    address: teams.event.team-member-suspended
    x-eventcatalog-role: provider
    messages:
      MemberSuspendedEvent:
        $ref: '#/components/messages/MemberSuspendedEvent'

  teams.event.team-member-unsuspended:
    address: teams.event.team-member-unsuspended
    x-eventcatalog-role: provider
    messages:
      MemberUnsuspendedEvent:
        $ref: '#/components/messages/MemberUnsuspendedEvent'

  teams.event.accept-invitation-failed:
    address: teams.event.accept-invitation-failed
    x-eventcatalog-role: provider
    messages:
      AcceptInvitationFailedEvent:
        $ref: '#/components/messages/AcceptInvitationFailedEvent'

  teams.event.team-invitation-initiated:
    address: teams.event.team-invitation-initiated
    x-eventcatalog-role: provider
    messages:
      InvitationInitiatedEvent:
        $ref: '#/components/messages/InvitationInitiatedEvent'

  teams.event.member-added-to-team:
    address: teams.event.member-added-to-team
    x-eventcatalog-role: provider
    messages:
      MemberAddedToTeamEvent:
        $ref: '#/components/messages/MemberAddedToTeamEvent'

  teams.event.link-user-to-organisation-failed:
    address: teams.event.link-user-to-organisation-failed
    x-eventcatalog-role: provider
    messages:
      LinkUserToOrganisationFailedEvent:
        $ref: '#/components/messages/LinkUserToOrganisationFailedEvent'

  teams.event.user-added-to-account:
    address: teams.event.user-added-to-account
    x-eventcatalog-role: provider
    messages:
      UserAddedToAccountEvent:
        $ref: '#/components/messages/UserAddedToAccountEvent'

  teams.event.user-removed-from-account:
    address: teams.event.user-removed-from-account
    x-eventcatalog-role: provider
    messages:
      UserRemovedFromAccountEvent:
        $ref: '#/components/messages/UserRemovedFromAccountEvent'

  authentication.event.user-personal-details-updated:
    address: authentication.event.user-personal-details-updated
    x-eventcatalog-role: provider
    messages:
      UserPersonalDetailsUpdatedEvent:
        $ref: '#/components/messages/UserPersonalDetailsUpdatedEvent'

components:
  messages:
    # Commands
    CreateTeamCommand:
      name: CreateTeam
      title: Create Team Command
      summary: Command to create a new team
      description: Instructs the system to create a new team owned by the specified user under a given organisation
      x-eventcatalog-message-type: command
      payload:
        $ref: '#/components/schemas/CreateTeam'
    AddTeamMemberCommand:
      name: AddTeamMember
      title: Add Team Member Command
      summary: Command to add a member to a team
      description: Instructs the system to add a user as a member of a specified team
      x-eventcatalog-message-type: command
      payload:
        $ref: '#/components/schemas/AddTeamMember'

    AcceptInvitationCommand:
      name: AcceptInvitation
      title: Accept Invitation Command
      summary: Command to accept a pending team invitation
      description: Instructs the system to accept a pending team invitation on behalf of a user
      x-eventcatalog-message-type: command
      payload:
        $ref: '#/components/schemas/AcceptInvitation'

    # Events
    TeamCreatedEvent:
      name: TeamCreated
      title: Team Created Event
      summary: Event indicating a new team has been created
      description: Published when a new team has been successfully created
      x-eventcatalog-message-type: event
      payload:
        $ref: '#/components/schemas/TeamCreated'

    MemberRoleUpdatedEvent:
      name: MemberRoleUpdated
      title: Member Role Updated Event
      summary: Event indicating a team member's role has been updated
      description: Published when the role of an existing member of a team has been changed
      x-eventcatalog-message-type: event
      payload:
        $ref: '#/components/schemas/MemberRoleUpdated'

    MemberSuspendedEvent:
      name: MemberSuspended
      title: Member Suspended Event
      summary: Event indicating a team member has been suspended
      description: Published when an existing member of a team has been suspended
      x-eventcatalog-message-type: event
      payload:
        $ref: '#/components/schemas/MemberSuspended'

    MemberUnsuspendedEvent:
      name: MemberUnsuspended
      title: Member Unsuspended Event
      summary: Event indicating a previously suspended team member has been reinstated
      description: Published when a previously suspended member of a team has been reinstated
      x-eventcatalog-message-type: event
      payload:
        $ref: '#/components/schemas/MemberUnsuspended'

    AcceptInvitationFailedEvent:
      name: AcceptInvitationFailed
      title: Accept Invitation Failed Event
      summary: Event indicating an attempt to accept a team invitation has failed
      description: Published when an attempt to accept a pending team invitation has failed, with failure details
      x-eventcatalog-message-type: event
      payload:
        $ref: '#/components/schemas/AcceptInvitationFailed'

    InvitationInitiatedEvent:
      name: InvitationInitiated
      title: Invitation Initiated Event
      summary: Event indicating a team invitation has been initiated
      description: Published when a team invitation has been created and is ready to be delivered to the invitee
      x-eventcatalog-message-type: event
      payload:
        $ref: '#/components/schemas/InvitationInitiated'

    MemberAddedToTeamEvent:
      name: MemberAddedToTeam
      title: Member Added To Team Event
      summary: Event indicating a member has been added to a team
      description: Published by the invitation-acceptance workflow after a member has been added to the team and linked to the organisation
      x-eventcatalog-message-type: event
      payload:
        $ref: '#/components/schemas/MemberAddedToTeam'

    LinkUserToOrganisationFailedEvent:
      name: LinkUserToOrganisationFailed
      title: Link User To Organisation Failed Event
      summary: Event indicating linking a user to an organisation via invitation has failed
      description: Published by the invitation-acceptance workflow when linking the user to the organisation could not be completed
      x-eventcatalog-message-type: event
      payload:
        $ref: '#/components/schemas/LinkUserToOrganisationFailed'

    UserAddedToAccountEvent:
      name: UserAddedToAccount
      title: User Added To Account Event
      summary: Event indicating a user has been granted access to an account
      description: Published when a user has been added to the list of users with access to an account. Consumed by the accounts service to append the user to the account's user list.
      x-eventcatalog-message-type: event
      payload:
        $ref: '#/components/schemas/UserAddedToAccount'

    UserRemovedFromAccountEvent:
      name: UserRemovedFromAccount
      title: User Removed From Account Event
      summary: Event indicating a user's access to an account has been revoked
      description: Published when a user has been removed from the list of users with access to an account. Consumed by the accounts service to remove the user from the account's user list.
      x-eventcatalog-message-type: event
      payload:
        $ref: '#/components/schemas/UserRemovedFromAccount'

    UserPersonalDetailsUpdatedEvent:
      name: UserPersonalDetailsUpdated
      title: User Personal Details Updated Event
      summary: Event indicating a user's personal details have been updated
      description: Published when a user's personal details (first name, last name) have been updated. Consumed by the teams service to keep team member information in sync.
      x-eventcatalog-message-type: event
      payload:
        $ref: '#/components/schemas/UserPersonalDetailsUpdated'

  schemas:
    # Base Types
    Message:
      type: object
      description: Base message type that all commands and events inherit from
      required:
        - id
      properties:
        id:
          type: string
          description: Unique identifier for the message, typically a UUID
          default: UUID generated string

    Command:
      description: Base type for all commands in the system
      allOf:
        - $ref: '#/components/schemas/Message'

    Event:
      description: Base type for all events in the system
      allOf:
        - $ref: '#/components/schemas/Message'

    # Entity Types
    Owner:
      type: object
      description: Represents the initial owner of a team being created
      required:
        - userId
        - name
      properties:
        userId:
          type: string
          description: The identifier of the user who will own the team
        name:
          type: string
          description: The display name of the owner
        roleId:
          type: string
          description: The role id to be assigned to the owner user. If not provided, the default role OWNER will be used.

    Failure:
      type: object
      description: Represents a failure condition with error code and reason
      required:
        - code
        - reason
      properties:
        code:
          type: string
          description: The error code identifying the type of failure
        reason:
          type: string
          description: Human-readable description of the failure reason

    # Command Schemas
    AddTeamMember:
      allOf:
        - $ref: '#/components/schemas/Command'
        - type: object
          description: Command to add a member to a team
          required:
            - userId
            - teamId
            - roleId
          properties:
            userId:
              type: string
              description: The user id of the member to be added to the team
              example: db274344-8ffb-4c31-a743-448ffb4c3137
            teamId:
              type: string
              description: The system identifier of the team to which the member is being added
            roleId:
              type: string
              description: The identifier of the new role assigned to the member
            status:
              $ref: '#/components/schemas/Status'
              description: The initial activity status of the member being added to the team. ACTIVE by default.

    Status:
      type: string
      description: Represents the activity status
      enum:
        - INACTIVE
        - ACTIVE
      example: "ACTIVE"

    CreateTeam:
      allOf:
        - $ref: '#/components/schemas/Command'
        - type: object
          description: Command to create a new team under an organisation, with an initial owner
          required:
            - owner
            - teamName
            - organisationPartyId
          properties:
            owner:
              $ref: '#/components/schemas/Owner'
              description: The user who will be the initial owner of the team
            teamName:
              type: string
              description: The name of the team to be created
            organisationPartyId:
              type: string
              description: The identifier of the organisation party under which the team is being created

    AcceptInvitation:
      allOf:
        - $ref: '#/components/schemas/Command'
        - type: object
          description: Command to accept a pending team invitation on behalf of a user
          required:
            - invitationId
            - userId
            - name
          properties:
            invitationId:
              type: string
              description: The identifier of the invitation being accepted
            userId:
              type: string
              description: The identifier of the user accepting the invitation
            name:
              type: string
              description: The display name of the user accepting the invitation

    # Event Schemas
    TeamCreated:
      allOf:
        - $ref: '#/components/schemas/Event'
        - type: object
          description: Event published when a new team has been successfully created
          required:
            - teamName
            - teamId
          properties:
            teamName:
              type: string
              description: The name of the newly created team
            teamId:
              type: string
              description: The system identifier of the newly created team

    MemberRoleUpdated:
      allOf:
        - $ref: '#/components/schemas/Event'
        - type: object
          description: Event published when a team member's role has been updated
          required:
            - userId
            - teamName
            - roleId
            - organisationPartyId
            - changedBy
            - modifiedAt
          properties:
            userId:
              type: string
              description: The identifier of the user whose role was updated
            teamName:
              type: string
              description: The name of the team in which the role was updated
            roleId:
              type: string
              description: The identifier of the new role assigned to the member
            organisationPartyId:
              type: string
              description: The identifier of the organisation party under which the team belongs
            changedBy:
              type: string
              description: The identifier of the user who performed the role change
            modifiedAt:
              type: string
              format: date-time
              description: The timestamp when the role update was published; used by consumers to order events

    MemberSuspended:
      allOf:
        - $ref: '#/components/schemas/Event'
        - type: object
          description: Event published when a team member has been suspended
          required:
            - userId
            - teamName
            - organisationPartyId
            - changedBy
            - modifiedAt
          properties:
            userId:
              type: string
              description: The identifier of the user who has been suspended
            teamName:
              type: string
              description: The name of the team in which the member was suspended
            organisationPartyId:
              type: string
              description: The identifier of the organisation party under which the team belongs
            changedBy:
              type: string
              description: The identifier of the user who performed the suspension
            modifiedAt:
              type: string
              format: date-time
              description: The timestamp when the suspension was published; used by consumers to order events

    MemberUnsuspended:
      allOf:
        - $ref: '#/components/schemas/Event'
        - type: object
          description: Event published when a previously suspended team member has been reinstated
          required:
            - userId
            - teamName
            - organisationPartyId
            - changedBy
            - modifiedAt
          properties:
            userId:
              type: string
              description: The identifier of the user who has been reinstated
            teamName:
              type: string
              description: The name of the team in which the member was reinstated
            organisationPartyId:
              type: string
              description: The identifier of the organisation party under which the team belongs
            changedBy:
              type: string
              description: The identifier of the user who performed the reinstatement
            modifiedAt:
              type: string
              format: date-time
              description: The timestamp when the reinstatement was published; used by consumers to order events

    AcceptInvitationFailed:
      allOf:
        - $ref: '#/components/schemas/Event'
        - type: object
          description: Event published when an attempt to accept a team invitation has failed
          required:
            - userId
            - invitationId
            - teamId
            - teamName
            - failure
          properties:
            userId:
              type: string
              description: The identifier of the user who attempted to accept the invitation
            invitationId:
              type: string
              description: The identifier of the invitation that failed to be accepted
            teamId:
              type: string
              description: The system identifier of the team the invitation was for
            teamName:
              type: string
              description: The name of the team the invitation was for
            failure:
              $ref: '#/components/schemas/Failure'
              description: Details about the failure

    InvitationInitiated:
      allOf:
        - $ref: '#/components/schemas/Event'
        - type: object
          description: Event published when a team invitation is initiated and needs to be delivered
          required:
            - organisationName
            - inviterName
            - invitationId
            - contactType
            - contactValue
          properties:
            organisationName:
              type: string
              description: The name of the organisation the invitee is being invited to
            inviterName:
              type: string
              description: The display name of the user who created the invitation
            invitationId:
              type: string
              description: The identifier of the invitation
            contactType:
              type: string
              description: The type of contact used to reach the invitee (e.g., EMAIL, PHONE_NUMBER)
            contactValue:
              type: string
              description: The contact value where the invitation should be delivered
            userId:
              type: string
              description: The identifier of the invitee if already known; optional

    MemberAddedToTeam:
      allOf:
        - $ref: '#/components/schemas/Event'
        - type: object
          description: Event published by the invitation-acceptance workflow after a member has been added to a team and linked to the organisation
          required:
            - userId
            - organisationMemberAssigned
          properties:
            userId:
              type: string
              description: The identifier of the user who has joined the team
            organisationMemberAssigned:
              type: object
              description: Container for the organisation-level membership assignment details
              required:
                - organisationId
              properties:
                organisationId:
                  type: string
                  description: The URI identifier of the organisation the member has been assigned to

    LinkUserToOrganisationFailed:
      allOf:
        - $ref: '#/components/schemas/Event'
        - type: object
          description: Event published by the invitation-acceptance workflow when linking the user to the organisation could not be completed
          required:
            - userId
            - invitationId
            - failure
          properties:
            userId:
              type: string
              description: The identifier of the user for whom the link attempt failed
            invitationId:
              type: string
              description: The identifier of the invitation being processed
            teamId:
              type: string
              description: The identifier of the team the invitation was for; optional if the link failed before team lookup
            teamName:
              type: string
              description: The name of the team the invitation was for; optional
            organisationName:
              type: string
              description: The name of the organisation the invitation was for; optional
            failure:
              $ref: '#/components/schemas/Failure'
              description: Details about the failure

    UserAddedToAccount:
      allOf:
        - $ref: '#/components/schemas/Event'
        - type: object
          description: Event published when a user has been granted access to an account. Consumed by the accounts service to append the user to the account's user list.
          required:
            - userId
            - originAccountId
          properties:
            userId:
              type: string
              description: The identifier of the user who has been granted access to the account
            originAccountId:
              type: string
              description: The origin identifier of the account the user has been added to

    UserRemovedFromAccount:
      allOf:
        - $ref: '#/components/schemas/Event'
        - type: object
          description: Event published when a user's access to an account has been revoked. Consumed by the accounts service to remove the user from the account's user list.
          required:
            - userId
            - originAccountId
          properties:
            userId:
              type: string
              description: The identifier of the user whose access has been revoked
            originAccountId:
              type: string
              description: The origin identifier of the account the user has been removed from

    UserPersonalDetailsUpdated:
      allOf:
        - $ref: '#/components/schemas/Event'
        - type: object
          description: Event published by the authentication service when a user's personal details are updated. Consumed by the teams service to keep team member information in sync.
          required:
            - userId
            - firstName
            - lastName
          properties:
            userId:
              type: string
              description: The identifier of the user whose personal details were updated
            firstName:
              type: string
              description: The updated first name of the user
            lastName:
              type: string
              description: The updated last name of the user